package com.netty.rpc.protocol.server;

import com.netty.rpc.monitor.trace.Monitor;
import com.netty.rpc.common.entity.NettyRpcRequest;
import com.netty.rpc.common.entity.NettyRpcResponse;
import com.netty.rpc.common.exception.CommonException;
import com.netty.rpc.util.NettyRpcApplication;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class RequestHandler extends AbstractRequestHandler {


    @Override
    public void handle(NettyRpcRequest request, NettyRpcResponse response) {
        if (request.isHeatBeat()) {
            return;
        }
        beforeHandle(response);
        Object serviceBean = null;
        try {
            serviceBean = getInvokeBean(request);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new CommonException("no bean found for handle request");

        }
        if (serviceBean == null) {
            throw new CommonException("no bean found for handle request");
        }
        Class<?> clz = serviceBean.getClass();
        // 获取所要调用的方法
        Method method;
        Object result = null;
        try {
            method = clz.getMethod(request.getMethod(), request.getParamTypes());
            result = method.invoke(serviceBean, request.getParams());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //TODO monitor
        response.setMessageId(request.getMessageId());
        response.setInterfaze(request.getInterfaze());
        response.setSyn(request.isSyn());
        response.setStartTime(request.getStartTime());
        response.setResult(result);
        response.setTraceId(request.getTraceId());
        afterHandle(response);

        Monitor monitor = excutorContainer.getMonitor();
        if (monitor != null) {
            monitor.execute(monitor.create(response));
        }

    }

    private Object getInvokeBean(NettyRpcRequest request) throws ClassNotFoundException {

        String rpcClz = request.getRpcClz();
        Class clz;
        if (!StringUtils.isEmpty(rpcClz)) {
            clz = Class.forName(rpcClz);
            return NettyRpcApplication.getBean(clz);
        }
        clz = Class.forName(request.getInterfaze());
        return NettyRpcApplication.getBean(clz);
    }
}
